home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
- #include <io.h>
- #include <dos.h>
-
- #include "global.h"
- #include "config.h"
- #include "domain.h"
- #include "socket.h"
- #include "netuser.h"
- #include "files.h"
- #include "cmdparse.h"
-
- struct dserver *Dlist = NULLDOM;
-
- #ifdef ENH
- static struct rr *Rrlist[NRLIST];
- #endif
-
- int Dhaveaa = 1;
- int DBloaded = 0;
- int Db_initialize = 0;
- int DTranslate = 0;
- int DVerbose = 1;
- int Dcache_size = 20;
- int Cwrite = 0;
-
- static int16 Dtimeout = 60;
- int16 Dretries = 2;
-
- char *Dsuffix = NULLCHAR;
-
- int Dstypes[] = {
- TYPE_SOA,
- TYPE_NS,
- TYPE_MX,
- TYPE_MD,
- TYPE_MF,
- TYPE_CNAME,
- TYPE_PTR,
- TYPE_A,
- TYPE_MB,
- TYPE_MG,
- TYPE_MR,
- TYPE_NULL,
- TYPE_WKS,
- TYPE_HINFO,
- TYPE_MINFO,
- TYPE_TXT,
- 0
- };
-
- /*----------------------------------------------------------------------*
- * list the cache entries *
- *-----------------------------------------------------------------------*/
- static int
- docachelist(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
- char buf[80];
- Cache *cap = cache;
-
- tputs("Status Address Name\n");
- for (i = 0; i < Dcache_size; i++) {
- if(i == Dcache_size)
- break;
- if (cap->ti) {
- sprintf(buf,"%u.%u.%u.%u", /* always print the ip-address */
- hibyte(hiword(cap->address)), /* even if DTranslate is set */
- lobyte(hiword(cap->address)),
- hibyte(loword(cap->address)),
- lobyte(loword(cap->address)) );
- tprintf("%-9.9s%-19s%s\n",
- (cap->type == Found) ? "Valid" : "Invalid",buf,cap->name);
- }
- cap++;
- }
- return(0);
- }
-
- static int
- docachegarb(int argc,char *argv[],void *p)
- {
- int i;
- Cache *cap = cache;
-
- semwait(&Cwrite,1);
-
- for(i = 0; i < Dcache_size; i++) {
- if(cap->type == Missing || cap->address == 0) {
- cap->ti = 0;
- memset(cap->name,0,5);
- }
- cap++;
- }
- semrel(&Cwrite);
- return 0;
- }
-
- /*----------------------------------------------------------------------*
- * change the cache size
- *-----------------------------------------------------------------------*/
- static int
- docachesize(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int result = 0, newsize = Dcache_size;
-
- if ((result = setintrc(&(int16)newsize,"DOM cache size",argc,argv,2,50)) == 0) {
- if(argc > 1 && newsize > 0){
- semwait(&Cwrite,1); /* lock again */
- Dcache_size = newsize;
- xfree(cache);
- cache = cxallocw(sizeof(Cache),(newsize + 2));
- semrel(&Cwrite);
- }
- }
- return result;
- }
-
- static int
- doadds(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct dserver *dp;
- int32 address;
-
- if((address = resolve(argv[1])) == 0){
- tprintf(Badhost,argv[1]);
- return 1;
- }
- if(address == Ip_addr) {
- tputs("Use 'start domain'\n");
- } else {
- dp = (struct dserver *)mxallocw(sizeof(struct dserver));
- dp->address = address;
- dp->port = (argc < 3) ? IPPORT_DOMAIN : atoi(argv[2]);
-
- /* Pick a wait time for response: it takes about 15 sec on my AT
- * to scan trough the domain.txt file. Taking 3 scans (max)
- * and giving a little strech to the channel i come to 60 secs */
- dp->srtt = dp->timeout = Dtimeout * 1000L;
- dp->mdev = 0;
- dp->next = Dlist;
- Dlist = dp;
- Dhaveaa = 0; /* another is also responsible */
- }
- return 0;
- }
-
- static int
- dodfile(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2 && Dfile != NULLCHAR)
- tprintf("%s\n",Dfile);
- else {
- if(access(argv[1],0) == 0) {
- xfree(Dfile);
- Dfile = strxdup(argv[1]);
- } else {
- tputs("No such domain file\n");
- return -1;
- }
- }
- return 0;
- }
-
- static int
- dodropds(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct dserver *dp, *dptmp = NULLDOM;
- int32 addr;
-
- if((addr = resolve(argv[1])) == 0) {
- tprintf(Badhost,argv[1]);
- } else {
- for(dp = Dlist; dp != NULLDOM; dptmp = dp, dp = dp->next)
- if(dp->address == addr) {
- if(dptmp != NULLDOM)
- dptmp->next = dp->next;
- else
- Dlist = dp->next;
- xfree((char *)dp);
- if(Dlist == NULLDOM)
- Dhaveaa = 1;
- return 0;
- }
- }
- return -1;
- }
-
- static int
- dolistds(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct dserver *dp;
-
- tputs("Server srtt mdev timeout queries responses timeouts\n");
- for(dp = Dlist; dp != NULLDOM; dp = dp->next) {
- tprintf("%-16s%-8lu%-8lu%-8lu%-8lu%-10lu%-8lu\n",
- inet_ntoa(dp->address),
- dp->srtt,dp->mdev,dp->timeout,
- dp->queries,dp->responses,dp->missers);
- }
- return 0;
- }
-
- #ifdef ENH
- static int
- doload(argc,argv,pp)
- int argc;
- char *argv[];
- void *pp;
- {
- FILE *dbase;
- int type, numbscan = 0, numbload = 0;
- long rrsize = 0;
- struct rr *rrp, *rrl, *db_SOA;
- struct rr_memory *memory;
- char *arg[2];
- char Recload[] = "Number of %srecords scanned %d loaded %d\n";
-
- arg[0] = NULLCHAR;
- arg[2] = NULLCHAR;
-
- if((dbase = open_file((argc < 3) ? Dfile : argv[1],READ_TEXT,0,1)) == NULLFILE)
- return 1;
- memory = (struct rr_memory *)mxallocw(sizeof(struct rr_memory));
-
- db_SOA = NULLRR;
-
- if(Lorigin == NULLDLIST) {
- Lorigin = (struct dlist *)mxallocw(sizeof(struct dlist));
- Lorigin->name = ""; /* start with empty domain name */
- Db_initialize = 1;
- while((rrp = get_rr(dbase,memory)) != NULLRR) {
- type = rrp->type;
- numbscan++;
- numbload++;
- rrsize += (long)rrp->rdlength;
- if(type == TYPE_SOA)
- db_SOA = rrp; /* save for reference */
- else
- rrp->soarec = db_SOA;
- if(Rrlist[type] == NULLRR) {
- Rrlist[type] = rrp; /* initialize linked list */
- Rrlistl[type] = rrp;
- } else {
- Rrlistl[type]->next = rrp;
- Rrlistl[type] = rrp; /* append to linked list */
- }
- }
- /* Lorigin stayes as a list of loaded domain origin names.
- * it is refered to in rrp->origins loaded in memory.
- * having a common origin saves significantly in used
- * memory oposed to giving every record a copy of that
- * origin. Domain save will reconstruct $origin statements.
- */
- tprintf(Recload,"",numbscan,numbload);
- tprintf("Memory record size %d extra %ld\n",sizeof(struct rr),rrsize);
- Db_initialize = 0;
- Dorigin = NULLCHAR; /* not loading anymore */
- DBloaded = 1; /* disable domain file access */
- } else {
- Db_initialize = 1;
- while((rrp = get_rr(dbase,memory)) != NULLRR) {
- numbscan++;
- type = rrp->type;
- if(type == TYPE_SOA)
- db_SOA = rrp; /* save for reference */
- else
- rrp->soarec = db_SOA;
- fflush(stdout);
- if(add_rr(NULLFILE,rrp))
- free_rr(rrp);
- else
- numbload++;
- }
- tprintf(Recload,"additional ",numbscan,numbload);
- Db_initialize = 0;
- Dorigin = NULLCHAR; /* not loading anymore */
- fclose(dbase);
- xfree((char *)memory);
- return 0;
- }
- fclose(dbase);
- xfree(memory->dorigin);
- xfree((char *)memory);
- if((rrp = Rrlist[TYPE_NS]) != NULLRR) {
- rrl = rrp;
- while(rrl != NULLRR) {
- arg[1] = rrl->rdata.name;
- doadds(2,arg,pp);
- rrl = rrl->next;
- }
- }
- return 0;
- }
- #endif
-
- #ifdef ENH
- static int
- donslookup(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i, len, type = 0;
- int16 flags;
- int32 address;
- char *buf;
- struct dhdr *dhdr;
- struct mbuf *bp;
-
- if((address = resolve(argv[1])) == 0) {
- tprintf(Badhost,argv[1]);
- return 1;
- }
- if(isdigit(*argv[2])) {
- type = atoi(argv[2]);
- if(type > 255)
- type = 0;
- } else {
- for(i = 0; i < NRLIST; i++) {
- if(stricmp(argv[2],type2str(i)) == 0){
- type = i;
- break;
- }
- }
- }
- if(type == 0){
- tprintf("Unknown record type %s\n",argv[2]);
- return 1;
- }
-
- flags = DOM_DORECURSE | DOM_CANRECURSE; /* Recursion desired */
- dhdr = bld_dhdr(QUERY,QUERY,flags,NO_ERROR,argv[3],CLASS_IN,type);
- buf = mxallocw(512);
- len = res_mkbuf(dhdr,buf,512);
- free_dhdr(dhdr);
- for(;;) {
- if(sendquery(address,buf,len,&bp,Dtimeout * 1000) > 0) {
- dhdr = (struct dhdr *)mxallocw(sizeof(struct dhdr));
- ntohdomain(dhdr,&bp);
- proc_answer(dhdr,NULLDOM,NULLFILE);
- free_dhdr(dhdr);
- tputs("NS lookup: host added\n");
- } else {
- tputs("NS lookup: timeout\n");
- }
- break;
- }
- return 0;
- }
- #endif
-
- static int
- doretries(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setintrc(&Dretries,"DOM retries",argc,argv,1,10);
- }
-
- #ifdef ENH
- static int
- dosave(argc,argv,pp)
- int argc;
- char *argv[];
- void *pp;
- {
- FILE *dbase;
- int i, j;
- struct rr *rrp;
- struct dlist *llist;
- char *p;
-
- if((dbase = open_file((argc < 3) ? "/domain.new" : argv[1],WRITE_TEXT,0,1)) == NULLFILE)
- return 1;
- if((llist = Lorigin) != NULLDLIST) {
- while(llist != NULLDLIST) {
- fprintf(dbase,"$origin\t%s\n",llist->name);
- for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++) {
- if((rrp = Rrlist[j]) != NULLRR) {
- while(rrp != NULLRR) {
- if((*llist->name == '\0')
- && (rrp->origin == NULLCHAR)) {
- if(rrp->type != TYPE_A)
- put_rr(dbase,rrp,0);
- else if(rrp->rdata.addr != 0)
- put_rr(dbase,rrp,0);
- } else if(rrp->origin == llist->name) {
- if(rrp->type != TYPE_A)
- put_rr(dbase,rrp,0);
- else
- if( rrp->rdata.addr != 0)
- put_rr(dbase,rrp,0);
- }
- rrp = rrp->next;
- }
- }
- }
- llist = llist->next;
- }
- } else for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++) {
- p = NULLCHAR;
- if((rrp = Rrlist[j]) != NULLRR) {
- while(rrp != NULLRR) {
- if(rrp->name[strlen(rrp->name) - 1] != '.') {
- if(p == NULLCHAR && rrp->origin != NULLCHAR)
- fprintf(dbase,"$origin %s\n",rrp->origin);
- if(p != NULLCHAR && rrp->origin == NULLCHAR)
- fputs("$origin \n",dbase);
- if(p != NULLCHAR && rrp->origin != NULLCHAR)
- if(stricmp(p,rrp->origin))
- fprintf(dbase,"$origin %s\n",rrp->origin);
- p = rrp->origin;
- }
- if(rrp->type != TYPE_A)
- put_rr(dbase,rrp,0);
- else
- if( rrp->rdata.addr != 0)
- put_rr(dbase,rrp,0);
- rrp = rrp->next;
- }
- }
- }
- fclose(dbase);
- return 0;
- }
- #endif
-
- static int
- dosuffix(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2){
- if(Dsuffix != NULLCHAR)
- tprintf("%s\n",Dsuffix);
- } else {
- if(strcmp(argv[1],"none") == 0) {
- xfree(Dsuffix);
- Dsuffix = NULLCHAR; /* clear out suffix */
- } else {
- int i = strlen(argv[1]) - 1;
- xfree(Dsuffix);
- Dsuffix = mxallocw(i + 3);
- strcpy(Dsuffix,argv[1]);
- if(argv[1][i] != '.')
- strcat(Dsuffix,".");
- }
- }
- return 0;
- }
-
- static int
- dotimeout(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setintrc(&Dtimeout,"DOM timeout",argc,argv,2,120);
- }
-
- static int
- dotranslate(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&DTranslate,"DOM translate",argc,argv);
- }
-
- static int
- doverbose(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&DVerbose,"DOM verbose",argc,argv);
- }
-
- #ifdef ENH
- static int
- dozoneinit(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct dhdr *dhdr;
- struct dserver *dp;
- struct sockaddr_in server;
- int32 address;
- int16 flags;
- char *buf, *bootname, *domainname;
- int len, s, resp;
- struct mbuf *bp;
- FILE *fp;
- char *name = argv[1];
-
- if(*name == '[')
- address = aton(name+1);
- else
- if(isaddr(name))
- address = aton(name);
- else {
- tprintf("Can't resolve %s currently\n",argv[1]);
- return 1;
- }
-
- dp = (struct dserver *)mxallocw(sizeof(struct dserver));
- dp->srtt = dp->timeout = Dtimeout * 1000;
- dp->mdev = 0;
-
- DBloaded = 1; /* disable domain file access */
- bootname = (argc > 2) ? argv[2] : "/domain.txt";
- domainname = (argc > 3) ? argv[3] : "/domain.new";
-
- /* do zoneinit from remote server */
- server.sin_family = AF_INET;
- server.sin_port = IPPORT_DOMAIN;
- server.sin_addr.s_addr = address;
- flags = DOM_DORECURSE | DOM_CANRECURSE; /* Recursion desired */
- buf = mxallocw(512);
- dhdr = bld_dhdr(QUERY,ZONEINIT,flags,NO_ERROR,bootname,CLASS_IN,TYPE_ANY);
- len = res_mkbuf(dhdr,buf,512);
- bp = qdata(buf,(int16)len);
- if((fp = open_file(domainname,WRITE_TEXT,0,1)) != NULLFILE) {
- if((s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
- send_mbuf(s,bp,0,(char *)&server,sizeof(server));
- for(;;) {
- alarm(dp->timeout);
- resp = recv_mbuf(s,&bp,0,NULLCHAR,0);
- alarm(0L);
- if(resp == -1)
- break;
- ntohdomain(dhdr,&bp);
- proc_answer(dhdr,dp,fp);
- }
- close_s(s);
- }
- fclose(fp);
- }
- xfree(buf);
- free_dhdr(dhdr);
- xfree((char *)dp);
- DBloaded = 0;
- return 0;
- }
- #endif
-
- static int
- docache(int argc,char *argv[],void *p)
- {
- struct cmds Dcachecmds[] = {
- "garb", docachegarb, 0, 0, NULLCHAR,
- "list", docachelist, 0, 0, NULLCHAR,
- "size", docachesize, 0, 0, NULLCHAR,
- NULLCHAR,
- };
- return subcmd(Dcachecmds,argc,argv,p);
- }
-
- int
- dodomain(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct cmds Dcmds[] = {
- "add", doadds, 0, 2,
- "domain add <server> [<port>]",
- "cache", docache, 0, 0,
- NULLCHAR,
- "dfile", dodfile, 0, 0,
- NULLCHAR,
- "drop", dodropds, 0, 2,
- "domain drop <server>",
- "list", dolistds, 0, 0,
- NULLCHAR,
- #ifdef ENH
- "load", doload, 0, 0,
- "domain load [<filename>]",
- "nslookup", donslookup, 1024, 4,
- "domain nslookup <server> <record type> <name>",
- #endif
- "retries", doretries, 0, 0,
- NULLCHAR,
- #ifdef ENH
- "save", dosave, 0, 0,
- "domain save [<filename>]",
- #endif
- "suffix", dosuffix, 0, 0,
- NULLCHAR,
- "timeout", dotimeout, 0, 0,
- NULLCHAR,
- "translate",dotranslate,0, 0,
- NULLCHAR,
- "verbose", doverbose, 0, 0,
- NULLCHAR,
- #ifdef ENH
- "zoneinit", dozoneinit, 1024, 2,
- "domain zoneinit <server> [<filename>]",
- #endif
- NULLCHAR,
- };
-
- return subcmd(Dcmds,argc,argv,p);
- }
-